package com.zh.work.aop;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.zh.common.entity.Oauth;
import com.zh.common.util.CheckObjAllFieldsIsNullUtil;
import com.zh.common.util.IpAddressUtil;
import com.zh.work.entity.MerchantRecordEntity;
import com.zh.work.entity.merch.ChangeMerchInfoEntity;
import com.zh.work.entity.merch.ChangeMerchRateEntity;
import com.zh.work.entity.merch.MerchInfoEntity;
import com.zh.work.service.platform.merch.MerchInfoService;
import io.swagger.annotations.ApiOperation;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;

/**
 * code is far away from bug with the animal protecting
 * ┏┓　　　┏┓
 * ┏┛┻━━━┛┻┓
 * ┃　　　　　　　┃
 * ┃　　　━　　　┃
 * ┃　┳┛　┗┳　┃
 * ┃　　　　　　　┃
 * ┃　　　┻　　　┃
 * ┃　　　　　　　┃
 * ┗━┓　　　┏━┛
 * 　　┃　　　┃神兽保佑
 * 　　┃　　　┃代码无BUG！
 * 　　┃　　　┗━━━┓
 * 　　┃　　　　　　　┣┓
 * 　　┃　　　　　　　┏┛
 * 　　┗┓┓┏━┳┓┏┛
 * 　　　┃┫┫　┃┫┫
 * 　　　┗┻┛　┗┻┛
 *
 * @Description: 商户操作AOP日志记录
 * @Author: Li.HuiNeng
 * @Create in: 2019-12-10 10:04
 * @Version: 1.0.1
 */
//@Aspect
//@Component
public class MerchantRecordAop {

    private static final Logger log = LoggerFactory.getLogger(MerchantRecordAop.class);

    @Autowired
    private MerchInfoService merchInfoService;

    @Pointcut("execution(* com.zh.work.controller.platform.merch..updateMerchantInfoById(..))")
    public void modRecordAopLog() { }



    // 获取当前时间
    private String DATE = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());

    @Async
    @Before(value = "modRecordAopLog()")
    public void BeforeMod(@NotNull JoinPoint jp) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        // 获取ip
        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        String ip = IpAddressUtil.getIpAddress(request);
        // 获取方法信息
        MethodSignature methodSignature = (MethodSignature) jp.getSignature();
        Method method = methodSignature.getMethod();
        // 获取当前操作人对象
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        Oauth auth = (Oauth) authentication.getPrincipal();
        /* 获取ApiOperation注解设置的notes描述内容作为信息 */
        ApiOperation apiOperation = null;
        if (method.isAnnotationPresent(ApiOperation.class)) {
            apiOperation = method.getAnnotation(ApiOperation.class);
        }
        // 表示结果是否成功
        int i = 0;
        JSONObject json;
        Long id = null;
        if (jp.getArgs() == null) {
            log.warn("修改前置增强,JoinPoint中传入目标方法的参数对象为空!");
            return;
        }
        json = CheckObjAllFieldsIsNullUtil.getReflect(jp.getArgs()[0]);
        MerchInfoEntity entity = JSON.parseObject(String.valueOf(json), MerchInfoEntity.class);
        Assert.notNull(json.get("Id"),"修改前置增强,主键为空!");
        id = Long.parseLong(json.get("Id").toString());
        // 获取修改前值
        MerchInfoEntity oriEntity = this.merchInfoService.getById(id);
        // 设置原费率
        ChangeMerchRateEntity rateEntity = new ChangeMerchRateEntity();
        rateEntity.setOrigAppCredit(oriEntity.getAppCredit());
        rateEntity.setOrigAppFixed(oriEntity.getAppFixed());
        rateEntity.setOrigAppRate(oriEntity.getAppRate());
        rateEntity.setOrigCreditFixed(oriEntity.getCreditFixed());
        rateEntity.setOrigDebitFixed(oriEntity.getDebitFixed());
        rateEntity.setOrigCreditFixed(oriEntity.getCreditFixed());
        rateEntity.setOrigT0Fixed(oriEntity.getT0Fixed());
        rateEntity.setOrigOnlineT1Rate(oriEntity.getManuRate());
        rateEntity.setOrigOnlineT0Rate(oriEntity.getT0Rate());
        rateEntity.setOrigDebitRate(oriEntity.getDebitRate());
        rateEntity.setOrigCreditRate(oriEntity.getCreditRate());
        rateEntity.setMposOrigT0Rate(oriEntity.getAppT0Rate());
        // 设置现费率
        rateEntity.setAppCredit(entity.getAppCredit());
        rateEntity.setAppFixed(entity.getAppFixed());
        rateEntity.setAppRate(entity.getAppRate());
        rateEntity.setCreditFixed(entity.getCreditFixed());
        rateEntity.setDebitFixed(entity.getDebitFixed());
        rateEntity.setCreditFixed(entity.getCreditFixed());
        rateEntity.setT0Fixed(entity.getT0Fixed());
        rateEntity.setOnlineT1Rate(entity.getManuRate());
        rateEntity.setOnlineT0Rate(entity.getGatewayRateT0());
        rateEntity.setDebitRate(entity.getDebitRate());
        rateEntity.setCreditRate(entity.getCreditRate());
        rateEntity.setMposT0Rate(entity.getAppT0Rate());
        // 设置其他信息
        rateEntity.setMerchId(entity.getId());
        rateEntity.setMerchName(entity.getMerchName());
        rateEntity.setAgentNo(entity.getSuperAgent());
        rateEntity.setUserName(auth.getUserLoginName());
        rateEntity.setAddTime(new Date());
        // 插入费率资料修改记录表信息
        if (rateEntity.insert()) {
            i = 1;
            log.info("插入一条商户费率资料修改记录，操作人=> {}", auth.getUserLoginName());
        }
        // 设置原基础信息
        ChangeMerchInfoEntity changeInfo = new ChangeMerchInfoEntity();
        changeInfo.setOrigAddress(oriEntity.getAddress());
        changeInfo.setOrigAreaCode(oriEntity.getProvinceCity());
        changeInfo.setOrigEmail(oriEntity.getEmail());
        changeInfo.setOrigLinkMan(oriEntity.getLinkMan());
        changeInfo.setOrigMobile(oriEntity.getMobile());
        changeInfo.setOrigTelephone(oriEntity.getTelephone());
        // 设置现基础信息
        changeInfo.setAddress(entity.getAddress());
        changeInfo.setAreaCode(entity.getProvinceCity());
        changeInfo.setEmail(entity.getEmail());
        changeInfo.setLinkMan(entity.getLinkMan());
        changeInfo.setMobile(entity.getMobile());
        changeInfo.setTelephone(entity.getTelephone());
        changeInfo.setMerchName(entity.getMerchName());
        changeInfo.setMerchId(entity.getId());
        // 其它基础信息
//        System.out.println(entity.getAuditStatus() != 1);
        if (entity.getAuditStatus() != 1) {
            changeInfo.setAuditStatus(entity.getAuditStatus());
            changeInfo.setAgentNo(entity.getSuperAgent());
            changeInfo.setAuditDate(entity.getAuditTime());
            changeInfo.setUserName(auth.getUserLoginName());
            changeInfo.setReason(entity.getRemark());
        }
        // 插入基础资料修改记录表信息
        if (changeInfo.insert()) {
            i = 1;
            log.info("插入一条商户基础资料修改记录，操作人=> {}", auth.getUserLoginName());
        }
        // 记录所有修改历史
        MerchantRecordEntity recordEntity = new MerchantRecordEntity();
        recordEntity.setBeforeValue(JSON.toJSONString(oriEntity));
        recordEntity.setAfterValue(json.toJSONString());
        recordEntity.setIp(ip);
        recordEntity.setOperatorId(auth.getId());
        recordEntity.setRequestFunc(method.getName());
        recordEntity.setSuccess(i > 0);
        if (this.merchInfoService.addMerchantRecord(recordEntity) > 0) {
            i = 1;
            log.info("请求记录:{}.{}==>[ {} ]", jp.getTarget().getClass().getName(), method.getName(), apiOperation.notes());
        }
    }

}
